package com.xplusplus.security.service;

import com.xplusplus.security.domain.Permission;
import com.xplusplus.security.domain.Role;
import com.xplusplus.security.domain.RolePermission;
import com.xplusplus.security.exception.EnumExceptions;
import com.xplusplus.security.exception.SecurityExceptions;
import com.xplusplus.security.repository.PermissionRepository;
import com.xplusplus.security.repository.RolePermissionRepository;
import com.xplusplus.security.repository.RoleRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @Author: Huxudong
 * @Description: 角色Service
 * @Date: Created in 12:39 2018/5/22
 * @Modified By:
 */
@Service
public class PermissionService {
    @Autowired
    private PermissionRepository permissionRepository;

    @Autowired
    private RolePermissionRepository rolePermissionRepository;

    @Autowired
    private RoleRepository roleRepository;

    /**
     * 新增角色
     */
    public Permission save(Permission permission){

        //验证是否存在
        if(permission == null
                ||(permission.getId() != null && permissionRepository.findOne(permission.getId()) != null)  ){
            throw new SecurityExceptions(EnumExceptions.ADD_FAILED_DUPLICATE);
        }
        return permissionRepository.save(permission);
    }

    /**
     * 更新角色
     */
    public Permission update(Permission permission){

        //验证是否存在
        if(permission == null || permission.getId() == null
                ||permissionRepository.findOne(permission.getId()) == null)  {
            throw new SecurityExceptions(EnumExceptions.UPDATE_FAILED_NOT_EXIST);
        }
        return permissionRepository.save(permission);
    }

    /**
     * 删除角色
     */
    public void delete(Integer id){

        //验证是否存在
        if(permissionRepository.findOne(id) == null){
            throw new SecurityExceptions(EnumExceptions.DELETE_FAILED_NOT_EXIST);
        }
        permissionRepository.delete(id);
    }

    /**
     * 批量删除角色
     */
    public void deleteInBatch(Integer[] ids){
        permissionRepository.deleteByIdIn(Arrays.asList(ids));
    }

    /**
     * 通过编号查询
     */
    public Permission findOne(Integer id){
        return permissionRepository.findOne(id);
    }

    /**
     * 查询所有
     */
    public List<Permission> findAll(){
        return permissionRepository.findAll();
    }

    /**
     * 查询所有-分页
     */
    public Page<Permission> findAllByPage(Integer page, Integer size, String sortFieldName, Integer asc){

        //判断排序字段名是否存在
        try{
            Permission.class.getDeclaredField(sortFieldName);
        }catch (Exception e){
            //如果不存在就设置为id
            sortFieldName = "id";
        }

        Sort sort =null;
        if(asc ==0 ){
            sort = new Sort(Sort.Direction.DESC, sortFieldName);
        }else {
            sort = new Sort(Sort.Direction.ASC, sortFieldName);
        }

        Pageable pageable = new PageRequest(page, size, sort);
        return permissionRepository.findAll(pageable);
    }

    /**
     * 通过名称模糊分页查询
     * @param name
     * @param page
     * @param size
     * @param sortFieldName
     * @param asc
     * @return
     */
    public Page<Permission> findByNameLikeByPage(String name, Integer page, Integer size,
                                                   String sortFieldName, Integer asc){

        //判断排序字段名是否存在
        try{
            Permission.class.getDeclaredField(sortFieldName);
        }catch (Exception e){
            //如果不存在就设置为id
            sortFieldName = "id";
        }

        Sort sort =null;
        if(asc ==0 ){
            sort = new Sort(Sort.Direction.DESC, sortFieldName);
        }else {
            sort = new Sort(Sort.Direction.ASC, sortFieldName);
        }

        Pageable pageable = new PageRequest(page, size, sort);
        return permissionRepository.findByNameLike("%" + name + "%",pageable);
    }

    /**
     * 通过权限查询角色
     *
     * @param permissionId
     * @return
     */
    public List<Role> getByRolesByPermissionId(Integer permissionId) {
        Permission permission = new Permission();
        permission.setId(permissionId);
        List<RolePermission> rolePermissions = rolePermissionRepository.findByPermission(permission);
        List<Role> roles = new ArrayList<>();
        for (RolePermission rolePermission : rolePermissions) {
            if(rolePermission.getRole() != null) {
                roles.add(rolePermission.getRole());
            }
        }
        return roles;
    }

    @Transactional
    public void assignRolesToPermission(Integer permissionId, Integer[] roleIds) {
        Permission permission = permissionRepository.findOne(permissionId);
        if(permission == null){
            throw new SecurityExceptions(EnumExceptions.ASSIGN_FAILED_PERMISSION_NOT_EXISTS);
        }
        rolePermissionRepository.deleteByPermission(permission);

        List<Role> roles = roleRepository.findByIdIn(Arrays.asList(roleIds));

        List<RolePermission> rolePermissions = new ArrayList<>();
        for (Role role : roles) {
            RolePermission rolePermission = new RolePermission();
            rolePermission.setRole(role);
            rolePermission.setPermission(permission);
            rolePermissions.add(rolePermission);
        }
        rolePermissionRepository.save(rolePermissions);
    }
}
